﻿using UnityEngine;
using UnityEngine.UI;

public class CameraSetup : MonoBehaviour
{
    [Header("相机参数")]
    public CameraData data;

    public float angle         => data.angle;
    public float EyeSeparation => data.EyeSeparation;
    public float NearClipPlane => data.NearClipPlane;
    public float FarClipPlane  => data.FarClipPlane;
    public float FieldOfView   => data.FieldOfView;
    public SteoroType steoroType => data.type;

    public RenderMode renderMode => data.renderMode;

    public RenderTextureFormat rtexFormat => data.rtexFormat;

    private float aspect;
    private bool isAwake = false;
    private bool isStereo = false;


    public enum SteoroType { 隔列, 隔行, 红蓝, 左右 };
    private string sidebysideColShader = "Custom/SideBySideStereoImageByCol";
    private string sidebysideRowShader = "Custom/SideBySideStereoImageByRow";
    private string anaglyphShader      = "Custom/anaglyphSteoro";
    private string sidebysideShader    = "Custom/SideBySideStereoImage";

  
    private Transform leftEyeCamera;
    private Transform rightEyeCamera;

    private RenderTexture rtexL;
    private RenderTexture rtexR;
    private RenderTexture rtexUI;
    private Image image;
 
    private Transform displayShow;
    private Transform display;


    public LayerMask mask;


    private int width  = Screen.width;
    private int height = Screen.height;

    private Canvas canvas;
    private  Camera uiCamera;

 

    void OnEnable() 
    {
        if (isAwake)
        {
            Set(true);
        }
        else
        {
            Logic();
        }
    }


    public void SetFieldView( float eye, float  angle)
    {
        leftEyeCamera.transform.localPosition  =  new Vector3(-eye, 0, 0);
        rightEyeCamera.transform.localPosition =  new Vector3(eye, 0, 0);

        leftEyeCamera.transform.localEulerAngles  = new Vector3(0, -angle, 0);
        rightEyeCamera.transform.localEulerAngles = new Vector3(0, angle, 0);
    }


    public void Set(bool action)
    {
        if (action) Logic();
        displayShow . gameObject . SetActive(action);
        display     . gameObject . SetActive(action);
    }


    [ContextMenu("Logic")]
    public void Logic()
    {
//+ renderTexture设置参数
        Shader shad = null;
             if (data.type == SteoroType.隔列)
            shad = Shader.Find(sidebysideColShader);
        else if (data.type == SteoroType.隔行)
            shad = Shader.Find(sidebysideRowShader);
        else if (data.type == SteoroType.红蓝)
            shad = Shader.Find(anaglyphShader);
        else if (data.type == SteoroType.左右)
            shad = Shader.Find(sidebysideShader);

        if (rtexL == null)
        {
            rtexL = new RenderTexture(width, height, 16, rtexFormat);
            rtexL.Create();
        }

        if (rtexR == null)
        {
            rtexR = new RenderTexture(width, height, 16, rtexFormat);
            rtexR.Create();
        }

        if (rtexUI == null)
        {
            rtexUI = new RenderTexture(width, height, 16, rtexFormat);
            rtexUI.Create();
        }

//+ 画布相机设置参数   
        display                = transform.Find("Show3DCamera");
        uiCamera               = display.GetComponent<Camera>();
      //  uiCamera.targetTexture = rtexUI;

//+ 相机设置参数
        leftEyeCamera  = CheckCamera("leftEyeCamera",rtexL);
        rightEyeCamera = CheckCamera("rightEyeCamera",rtexR);

        leftEyeCamera.transform.localPosition    = new Vector3(-EyeSeparation * 0.5f, 0, 0);
        leftEyeCamera.transform.localEulerAngles = new Vector3(0, -angle, 0);

        rightEyeCamera.transform.localPosition    = new Vector3(EyeSeparation * 0.5f, 0, 0);
        rightEyeCamera.transform.localEulerAngles = new Vector3(0, angle, 0);

//+ 画布渲染目标设置
        displayShow = transform.Find("SideBySide");
        displayShow.GetComponent<RectTransform>().sizeDelta = new Vector2(width, height);

        canvas = displayShow.GetComponent<Canvas>();
        canvas.renderMode = renderMode;


//+ 相机渲染目标设置
        image = displayShow.Find("Image").GetComponent<Image>();
        image.gameObject.SetActive(true);
        image.rectTransform.sizeDelta = new Vector2(width, height);
        image.material.shader         = shad;
        image.material.SetFloat("_ScreenWidth", width);
        image.material.SetFloat("_ScreenHeight", height);
        image.material.SetTexture("_LCamTex", rtexL);
        image.material.SetTexture("_RCamTex", rtexR);
        image.material.SetTextureOffset("_LCamTex", new Vector2(0, 0));
        image.material.SetTextureOffset("_RCamTex", new Vector2(0, 0));
        image.material.SetTextureScale("_LCamTex", new Vector2(1, 1));
        image.material.SetTextureScale("_RCamTex", new Vector2(1, 1));

        isStereo = true;

        //this.UpdateTime(2.0f).OnComelete(ModeChange);
    }

    private Transform CheckCamera(string cameraName,RenderTexture renderTx)
    {
        var cameraTransform = transform.Find($"Show3DCamera/{cameraName}");
        if (cameraTransform == null)
            cameraTransform = new GameObject(cameraName).transform;

        cameraTransform.transform.SetParent(display);

        var camera = cameraTransform.GetComponent<Camera>();
        if (camera == null)
            camera = cameraTransform.gameObject.AddComponent<Camera>();

        if (steoroType == SteoroType.隔行)
                 camera.rect = new Rect(0, 0, 1, 1);
            else camera.rect = new Rect(0, 0, 0.5f, 1);

        camera.fieldOfView = FieldOfView;

        if(aspect == 0)
           aspect = camera.aspect;

        if (steoroType == SteoroType.隔行)
            camera.aspect = aspect;
        else
            camera.aspect = aspect * 2;

        camera.nearClipPlane   = NearClipPlane;
        camera.farClipPlane    = FarClipPlane;
        camera.clearFlags      = CameraClearFlags.Skybox;
        camera.backgroundColor = new Color(0, 0, 0);
        camera.targetTexture   = renderTx;
        camera.targetDisplay   = 0;
        camera.cullingMask     = mask;

        return cameraTransform;
    }


    public void Check()
    {

        leftEyeCamera.transform.localPosition = new Vector3(-data.EyeSeparation / 2.0f, 0, 0);
        rightEyeCamera.transform.localPosition = new Vector3(data.EyeSeparation / 2.0f, 0, 0);


        leftEyeCamera.transform.localEulerAngles = new Vector3(0, -angle, 0);
        rightEyeCamera.transform.localEulerAngles = new Vector3(0, angle, 0);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            isStereo = false;
        }
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            isStereo = true;
        }

        if (!isStereo) return;

        else if (Input.GetKeyDown(KeyCode.O))
        {
            data.EyeSeparation += data.adjustEye;
        }
        else if (Input.GetKeyDown(KeyCode.P))
        {
            data.EyeSeparation -= data.adjustEye;
        }
        else if (Input.GetKeyDown(KeyCode.U))
        {
            data.angle -= data.adjustAngle;
        }
        else if (Input.GetKeyDown(KeyCode.I))
        {
            data.angle += data.adjustAngle;
        }


        leftEyeCamera.gameObject.SetActive(isStereo);
        rightEyeCamera.gameObject.SetActive(isStereo);




        // if (this.CheckValue(data.EyeSeparation,0))
        // {
        //     leftEyeCamera.transform.localPosition = new Vector3(-data.EyeSeparation / 2.0f, 0, 0);
        //     rightEyeCamera.transform.localPosition = new Vector3(data.EyeSeparation / 2.0f, 0, 0);
        // }

        // if (this.CheckValue(data.angle,1))
        // {
        //     leftEyeCamera.transform.localEulerAngles = new Vector3(0, -angle, 0);
        //     rightEyeCamera.transform.localEulerAngles = new Vector3(0, angle, 0);
        // }

        // if(this.CheckValue(data.renderMode,2))
        // {
        //     canvas.renderMode = data.renderMode;
        // }
    }

}
